/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package clases;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
    import java.io.FileOutputStream;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 * @Author Gimbet
 * Clase concreta que representa el objeto compuesto reporte, 
 * un reporte puede tener otros reportes una matriz una columna o 
 * un indicador
 */
public class Reporte extends Root implements Reportable {
        private Integer idreporte;
	private ArrayList<Reportable> reporte = new ArrayList<Reportable>(); // Puede ser arraylist hash table o arreglo. 
        private String nombre;
	private String fechaCreacion;
        private String codigoUnidad;
        private Integer codigoMatriz;
        private Integer codigoReporte;
        private Integer codigoTotalizacion;
        private int anoReporte;
        private int trimestreReporte;

    public Integer getCodigoTotalizacion() {
        return codigoTotalizacion;
    }

    public void setCodigoTotalizacion(Integer codigoTotalizacion) {
        this.codigoTotalizacion = codigoTotalizacion;
    }

    public int getAnoReporte() {
        return anoReporte;
    }

    public void setAnoReporte(int anoReporte) {
        this.anoReporte = anoReporte;
    }

    public Integer getCodigoReporte() {
        return codigoReporte;
    }

    public void setCodigoReporte(Integer codigoReporte) {
        this.codigoReporte = codigoReporte;
    }

    public int getTrimestreReporte() {
        return trimestreReporte;
    }

    public void setTrimestreReporte(int trimestreReporte) {
        this.trimestreReporte = trimestreReporte;
    }
        

    public ArrayList<Reportable> getReporte() {
        return reporte;
    }

    public void setReporte(ArrayList<Reportable> reporte) {
        this.reporte = reporte;
    }

    public Integer getCodigoMatriz() {
        return codigoMatriz;
    }

    public void setCodigoMatriz(Integer codigoMatriz) {
        this.codigoMatriz = codigoMatriz;
    }

    public String getCodigoUnidad() {
        return codigoUnidad;
    }

    public void setCodigoUnidad(String codigoUnidad) {
        this.codigoUnidad = codigoUnidad;
    }
	private boolean publico;

    public Reporte() {
           this.fechaCreacion = new GregorianCalendar().getTime().toString();
    }

    public String getFechaCreacion() {
        return fechaCreacion;
    }

    public void setFechaCreacion(String fechaCreacion) {
        this.fechaCreacion = fechaCreacion;
    }

    public boolean isPublico() {
        return publico;
    }

    public void setPublico(boolean publico) {
        this.publico = publico;
    }

    public Integer getIdreporte() {
        return idreporte;
    }

    public void setIdreporte(Integer idreporte) {
        this.idreporte = idreporte;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public void agregarElemento(Reportable r){
        this.reporte.add(r);
        
    }
    @Override
    public void imprimirArchivoTabla(FileOutputStream f) {
        
             // Se crea el libro
            HSSFWorkbook libro = new HSSFWorkbook();

            // Se crea una hoja dentro del libro
            HSSFSheet hoja = libro.createSheet();
            
             int numf = hoja.getLastRowNum();
           for (Reportable reportable : reporte) {
            //Aqui verificar si es una matriz, fila o reporte
            Matriz m = (Matriz)reportable;
           
            HSSFRow fila = hoja.createRow(numf);
            

            // Se crea una celda dentro de la fila
            HSSFCell celda = fila.createCell(0);

            // Se crea el contenido de la celda y se mete en ella.
            HSSFRichTextString texto = new HSSFRichTextString(m.getNombre());
            celda.setCellValue(texto);
           
           
                if (m.isPlan()){
                   this.crearMatriz(m,hoja);
                   numf = hoja.getLastRowNum();
                   hoja.createRow(++numf); // Una fila vacia
                }
             
                m.setPlan(false);
                if (m.isAjuste()){
                    System.out.println("Es ajuste");
                    this.crearMatriz(m,hoja);
                    numf = hoja.getLastRowNum();
                    hoja.createRow(++numf); // Una fila vacia
                }
               
                m.setAjuste(false);
                if (m.isEjec()){
                    this.crearMatriz(m,hoja);                      
                }
                numf++;
                fila = hoja.createRow(numf);
                celda = fila.createCell(0);

                // Se crea el contenido de la celda y se mete en ella.
                texto = new HSSFRichTextString("Fuente: "+m.getCodigoUnidad());
                celda.setCellValue(texto);
           
            }
              
        try {
            libro.write(f);
            f.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
     
     }

    @Override
    public void imprimirArchivoDoc(FileOutputStream f) {
     
      
        Document document = new Document();

        try {
            PdfWriter writer = PdfWriter.getInstance(document, f);
            document.open();
            //Titulo   
            document.addTitle(this.getNombre());
            //Encabezado
            Font fuente = new Font(Font.getFamily("Times New Roman"), 12, Font.NORMAL);
            DateFormat dates = new SimpleDateFormat("dd/MM/yyyy");
            Date date = new Date();
            String newLine = "\n";
            
            String fecha = dates.format(date);
            String[] fechaArr = fecha.split("/");
            int mes = Integer.parseInt(fechaArr[1]);
            String trimestre;
                   
            
            if (1<=mes && mes<=3){
                trimestre = "I";
            }
            else if (4<=mes && mes <=6){
                trimestre = "II";
            }
            else if (7<=mes && mes<=9){
                trimestre = "III";
            }
            else{
                trimestre="IV";
            }
            
            String encabezado = "Trimestre "+trimestre+newLine;
            
            Paragraph pa = new Paragraph(encabezado, fuente);
            pa.setSpacingBefore(20);
            pa.setSpacingAfter(10);
            pa.setIndentationLeft(50);
            document.add(pa);
            
            String nombre = this.getNombre().toUpperCase();
            Font fuenteNombre = new Font(Font.getFamily("Times New Roman"), 14, Font.BOLD);
            Font fuenteMatriz = new Font(Font.getFamily("Times New Roman"), 14, Font.NORMAL);
            Paragraph pa2 = new Paragraph(nombre,fuenteNombre);
            pa2.setSpacingBefore(50);
            pa2.setAlignment(1);
            document.add(pa2);
            document.add(new Paragraph(newLine));
            
            // Si existen elementos reportables, los imprimimos en tablas.
            System.out.println("Reporte.size"+ this.reporte.size());
              for(int i=0; i<this.reporte.size(); i++){
                  if (Matriz.class.isInstance(this.reporte.get(i))){
                      
                    Matriz m = (Matriz) this.reporte.get(i);
                    
                    System.out.println("Informacion matriz:" +m.getNombre());
                    Paragraph p = new Paragraph(m.getNombre(), fuenteMatriz);
                    
                    p.setSpacingBefore(20);
                    p.setSpacingAfter(10);
                    p.setIndentationLeft(20);
                    p.setAlignment(1);
                    document.add(p);
                    PdfPTable table;
                    System.out.println("Plan,Ajuste,Ejec"+m.isPlan()+" "+m.isAjuste()+" "+m.isEjec());
                    if (m.isPlan()){
                       table= this.crearTabla(m);
                       document.add(table);
                    }
                    m.setPlan(false);
                     document.add(new Paragraph(newLine));
                    if (m.isAjuste()){
                       table= this.crearTabla(m);
                       document.add(table);
                    }
                    m.setAjuste(false);
                     document.add(new Paragraph(newLine));
                    if (m.isEjec()){
                        table = this.crearTabla(m);
                        document.add(table);
                    }
                 }
                  else{
                      Totalizacion t = (Totalizacion) this.reporte.get(i);
                      Paragraph p = new Paragraph(t.getNombre(), fuenteMatriz);
                  //Aqui imprimire el total tambien.
                      document.add(p);
                  }
              }
              
             
             document.close();
             f.flush();
             f.close();
         
        } catch (Exception e) {
                        //imprimimos los errores
            System.err.println(e);
            e.printStackTrace();
        }
    }
/** Transforma las matrices en formato PDF
 * 
 * @param m  : Matriz
 * @return la tabla que representa a la matriz m
 */
    private PdfPTable crearTabla(Matriz m) throws DocumentException {
        
        PdfPTable table = new PdfPTable(m.getColumnas().size());
        table.setWidthPercentage(100);
        ArrayList<Columna> columnas = m.getColumnas(); 
        Font fuente = new Font(Font.getFamily("Times New Roman"), 11, Font.NORMAL);
        //Agregamos los header de las columnas 
        for(int j = 0; j<columnas.size(); j++){
            PdfPCell headerColumna = new PdfPCell(new Paragraph(columnas.get(j).getNombre(),fuente));
            
            headerColumna.setBackgroundColor(BaseColor.LIGHT_GRAY);
            headerColumna.setHorizontalAlignment(1); //Centralizado
            table.addCell(headerColumna);
        }
        ArrayList<Celda> filas = m.getFilas();
        for (int j= 0; j<filas.size(); j++){
            
            Celda fila = filas.get(j);
            System.out.println("Celda y si es dato: "+fila.getIdCelda()+" "+fila.getIdDato());
            PdfPCell celda;
          
            if (fila.getIdDato()== null){
                celda = new PdfPCell(new Paragraph(12,fila.getNombre(),fuente));
                celda.setHorizontalAlignment(0);
                
            }
            else{ //Obtengo su dato
                celda = new PdfPCell(new Paragraph(fila.getDato().getValor(),fuente));
                celda.setHorizontalAlignment(3);

            }
            celda.setPadding(1);
            table.addCell(celda);
        }

        return table;
                
    }

    private void crearMatriz(Matriz m, HSSFSheet hoja) {
                ArrayList<Columna> columnas = m.getColumnas();
                int numfila = hoja.getLastRowNum();
                HSSFRow header = hoja.createRow(++numfila);
             
                System.out.println("Cantidad de columnas "+columnas.size());
               
                for (int i=0;i<columnas.size();i++) {
                     HSSFCell celda = header.createCell(i);
                     celda.setCellValue(columnas.get(i).getNombre()); 
                     System.out.println("Numero de fila: " +numfila);
                }
               
                ArrayList<Celda>filas = m.getFilas();
                System.out.println("Cantidad de filas "+filas.size());
                 String celdaFinal="";
                 String celDato="";
                 numfila++;
                 HSSFRow fila = hoja.createRow(numfila);
                 System.out.println("Numero de fila: " +numfila);
                for (int i=0;i<filas.size();i++){
                              
                    if (filas.get(i).getIdDato() == null){
                        HSSFCell celdaMat = fila.createCell((i)%columnas.size());
                        celdaMat.setCellValue(filas.get(i).getNombre());
                    }
                    else{
                       celDato = filas.get(i).getDato().getValor();
                       HSSFCell celdaMat = fila.createCell((i)%columnas.size());
                       celdaMat.setCellValue(celDato);
                    }
                      
                      System.out.println("CeldaDato "+celDato);
             
                      if (i > 0 && (i+1)%columnas.size() == 0){
                          System.out.println("CeldaFinal, iteracion "+ celdaFinal+" "+i);
                          numfila++;
                          fila = hoja.createRow(numfila);
                          
                      }
                }
}
    
//    private void crearExcel(File f){
//
// try {
//    
//            FileWriter fr = new FileWriter(f);
//            PrintWriter pw = new PrintWriter(f);
//            for (Reportable reportable : reporte) {
//                
//               
//                Matriz m = (Matriz)reportable;
//                pw.print(m.getNombre()+"\n");
//                if (m.isPlan()){
//                    this.crearMatriz(m,pw);
//                    pw.print("\n\n");
//                }
//                m.setPlan(false);
//                if (m.isAjuste()){
//                    this.crearMatriz(m,pw);
//                    pw.print("\n\n");
//                }
//                m.setAjuste(false);
//                if (m.isEjec()){
//                    this.crearMatriz(m,pw);
//                    pw.print("\n\n");
//                }
//                
//            }
//              //Flush the output to the file
//                pw.flush();
//
//                //Close the Print Writer
//                pw.close();
//
//                //Close the File Writer
//                fr.close();       
//            } catch (IOException ex) {
//                Logger.getLogger(Reporte.class.getName()).log(Level.SEVERE, null, ex);
//            }
// 

}
    
